"""
健康检查服务
"""

import time
import logging
import os
from pathlib import Path
from typing import Dict, Any

try:
    import psutil
    PSUTIL_AVAILABLE = True
except ImportError:
    PSUTIL_AVAILABLE = False
    psutil = None

from ..core.config import settings

logger = logging.getLogger(__name__)

class HealthCheckService:
    """健康检查服务"""
    
    def __init__(self):
        self.start_time = time.time()
        self.service_name = "dialogue_service"
        self.version = "1.0.0"
    
    def get_basic_health(self) -> Dict[str, Any]:
        """基础健康检查"""
        return {
            "status": "healthy",
            "service": self.service_name,
            "version": self.version,
            "timestamp": time.time(),
            "uptime": time.time() - self.start_time
        }
    
    def get_detailed_health(self) -> Dict[str, Any]:
        """详细健康检查"""
        health_data = self.get_basic_health()
        
        # 检查系统资源
        health_data["system"] = self._check_system_resources()
        
        # 检查模型状态
        health_data["models"] = self._check_models_status()
        
        # 检查存储空间
        health_data["storage"] = self._check_storage_space()
        
        # 检查服务状态
        health_data["service_stats"] = self._check_service_status()
        
        # 检查关键目录
        health_data["directories"] = self._check_directories()
        
        # 综合健康状态
        health_data["overall_status"] = self._determine_overall_status(health_data)
        
        return health_data
    
    def _check_system_resources(self) -> Dict[str, Any]:
        """检查系统资源"""
        if not PSUTIL_AVAILABLE:
            return {
                "status": "warning",
                "message": "psutil not available, cannot check system resources"
            }
        
        try:
            # CPU 使用率
            cpu_percent = psutil.cpu_percent(interval=1)
            
            # 内存使用情况
            memory = psutil.virtual_memory()
            
            # 磁盘使用情况
            disk = psutil.disk_usage('/')
            
            return {
                "cpu": {
                    "percent": cpu_percent,
                    "status": "healthy" if cpu_percent < 80 else "warning" if cpu_percent < 95 else "critical"
                },
                "memory": {
                    "total": memory.total,
                    "available": memory.available,
                    "percent": memory.percent,
                    "status": "healthy" if memory.percent < 80 else "warning" if memory.percent < 90 else "critical"
                },
                "disk": {
                    "total": disk.total,
                    "free": disk.free,
                    "percent": (disk.used / disk.total) * 100,
                    "status": "healthy" if disk.free > 1024**3 else "warning" if disk.free > 512**3 else "critical"
                }
            }
        except Exception as e:
            logger.error(f"检查系统资源失败: {str(e)}")
            return {"error": str(e), "status": "error"}
    
    def _check_models_status(self) -> Dict[str, Any]:
        """检查模型状态"""
        try:
            # 使用绝对导入避免相对导入问题
            import sys
            from pathlib import Path
            
            # 添加项目根目录到路径
            project_root = Path(__file__).parent.parent.parent
            if str(project_root) not in sys.path:
                sys.path.insert(0, str(project_root))
            
            from local_model_cache import cache_manager
            
            model_status = cache_manager.verify_all_models_available()
            missing_models = [name for name, available in model_status.items() if not available]
            
            return {
                "models_available": model_status,
                "missing_models": missing_models,
                "all_models_loaded": len(missing_models) == 0,
                "status": "healthy" if len(missing_models) == 0 else "warning"
            }
        except Exception as e:
            logger.error(f"检查模型状态失败: {str(e)}")
            return {"error": str(e), "status": "error"}
    
    def _check_storage_space(self) -> Dict[str, Any]:
        """检查存储空间"""
        try:
            directories = {
                "uploads": settings.UPLOAD_DIR,
                "output": settings.OUTPUT_DIR,
                "logs": settings.LOGS_DIR,
                "models": settings.MODELS_DIR
            }
            
            storage_info = {}
            for name, path in directories.items():
                if path.exists():
                    # 计算目录大小
                    total_size = sum(f.stat().st_size for f in path.rglob('*') if f.is_file())
                    storage_info[name] = {
                        "path": str(path),
                        "size_bytes": total_size,
                        "size_mb": round(total_size / (1024 * 1024), 2),
                        "exists": True
                    }
                else:
                    storage_info[name] = {
                        "path": str(path),
                        "exists": False,
                        "status": "missing"
                    }
            
            return {
                "directories": storage_info,
                "status": "healthy"
            }
        except Exception as e:
            logger.error(f"检查存储空间失败: {str(e)}")
            return {"error": str(e), "status": "error"}
    
    def _check_service_status(self) -> Dict[str, Any]:
        """检查服务状态"""
        try:
            # 动态导入以避免循环导入
            from .dialogue_service import dialogue_service
            
            stats = dialogue_service.get_stats()
            
            # 检查是否有过多失败任务
            total_tasks = stats.get("total_tasks", 0)
            failed_tasks = stats.get("failed_tasks", 0)
            failure_rate = (failed_tasks / total_tasks * 100) if total_tasks > 0 else 0
            
            # 检查活跃任务数
            active_tasks = stats.get("active_tasks", 0)
            max_tasks = settings.MAX_CONCURRENT_TASKS
            
            return {
                "stats": stats,
                "failure_rate": failure_rate,
                "active_tasks_ratio": active_tasks / max_tasks if max_tasks > 0 else 0,
                "status": "healthy" if failure_rate < 10 and active_tasks < max_tasks else "warning"
            }
        except Exception as e:
            logger.error(f"检查服务状态失败: {str(e)}")
            return {"error": str(e), "status": "error"}
    
    def _check_directories(self) -> Dict[str, Any]:
        """检查关键目录"""
        directories = {
            "uploads": settings.UPLOAD_DIR,
            "output": settings.OUTPUT_DIR,
            "logs": settings.LOGS_DIR,
            "models": settings.MODELS_DIR
        }
        
        dir_status = {}
        all_good = True
        
        for name, path in directories.items():
            exists = path.exists()
            writable = path.is_dir() and os.access(path, os.W_OK) if exists else False
            
            dir_status[name] = {
                "path": str(path),
                "exists": exists,
                "writable": writable,
                "status": "healthy" if exists and writable else "error"
            }
            
            if not exists or not writable:
                all_good = False
        
        return {
            "directories": dir_status,
            "status": "healthy" if all_good else "error"
        }
    
    def _determine_overall_status(self, health_data: Dict[str, Any]) -> str:
        """确定整体健康状态"""
        statuses = []
        
        # 收集各个检查项的状态
        for key, value in health_data.items():
            if isinstance(value, dict) and "status" in value:
                statuses.append(value["status"])
            elif key == "system" and isinstance(value, dict):
                for component in ["cpu", "memory", "disk"]:
                    if component in value and "status" in value[component]:
                        statuses.append(value[component]["status"])
        
        # 根据优先级确定整体状态
        if "critical" in statuses or "error" in statuses:
            return "critical"
        elif "warning" in statuses:
            return "warning"
        elif statuses and all(s == "healthy" for s in statuses):
            return "healthy"
        else:
            return "unknown"

# 创建全局健康检查服务实例
health_service = HealthCheckService()